<?php

namespace app\models;

use app\components\BaseActiveRecord;
use Throwable;
use Yii;
use yii\caching\TagDependency;
use yii\db\ActiveRecord;
use yii\db\Exception;
use yii\db\StaleObjectException;

/**
 * This is the model class for table "{{%favorite}}".
 *
 * @property int $id
 * @property int $uid
 * @property int $book_id
 * @property int $create_time
 *
 * @property Book $book
 */
class UserFavorite extends BaseActiveRecord {

    const MAX_FAVORITE = 60;
    const CACHE_TAG = '%s_favorite';


    /**
     * {@inheritdoc}
     */
    public static function tableName() {
        return '{{%user_favorite}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules() {
        return [
            [['uid', 'book_id', 'create_time'], 'integer'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels() {
        return [
            'id' => Yii::t('app', 'ID'),
            'uid' => Yii::t('app', 'Uid'),
            'book_id' => Yii::t('app', 'Book ID'),
            'create_time' => Yii::t('app', 'Create Time'),
        ];
    }

    public function getBook() {
        return $this->hasOne(Book::class, ['id' => 'book_id']);
    }

    /**
     * @param $book_id
     * @return array
     * @throws Exception
     * @throws Throwable
     */
    public static function saveFavorite($book_id) {
        $uid = Yii::$app->user->id;
        if (!$uid) {
            return self::retErr('您还未登陆.');
        }

        $model = self::find()->where("uid = {$uid} and book_id = {$book_id}")->one();
        if ($model) {
            $model->delete();
            Book::updateAllCounters(['favorite_count' => -1], ['id' => $book_id]);
            return self::retOK(NULL, '取消收藏成功');
        }

        if (self::find()->where("uid = {$uid}")->count() >= self::MAX_FAVORITE) {
            return self::retErr('您的书架满了.');
        }

        $model = new UserFavorite();
        $model->book_id = $book_id;
        $model->uid = $uid;
        $model->saveSuccessMessage = '收藏成功';
        $res = $model->save();

        Book::updateAllCounters(['favorite_count' => 1], ['id' => $book_id]);
        return $res;
    }

    public static function getFavorite($book_id) {
        $uid = Yii::$app->user->id;
        if (!$uid) {
            return FALSE;
        }
        return self::find()->where("uid = {$uid} and book_id = {$book_id}")->one();
    }

    /**
     * @return array|ActiveRecord[]
     */
    public static function getFavorites() {
        $uid = Yii::$app->user->id;
        if (!$uid) {
            return [];
        }
        $TAG = sprintf(self::CACHE_TAG, $uid);
        $dependency = new TagDependency(['tags' => $TAG]);
        return self::find()->cache(0, $dependency)->where("uid = {$uid}")->with('book')->orderBy('id desc')->asArray()->all();
    }

    public static function deleteAllFavorite() {
        $uid = Yii::$app->user->id;
        if (!$uid) {
            return static::retOK();
        }
        $where = ['uid' => $uid];

        $models = self::find()->where($where)->asArray()->indexBy('book_id')->all();
        Book::updateAllCounters(['favorite_count' => -1], ['id' => array_keys($models)]);
        self::deleteAll($where);
        return self::retOK();
    }

    public function refreshCache() {
        $TAG = sprintf(self::CACHE_TAG, $this->uid);
        TagDependency::invalidate(Yii::$app->cache, $TAG);
    }
}
